package net.dgg.zz.common.utils;/**
 * Created by Administrator on 2018/1/8.
 */

import net.dgg.iboss.base.service.CmsService;
import net.dgg.iboss.base.util.DateUtil;
import net.dgg.zz.common.constant.ScProductConstant;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @author 刘阳
 * @ClassName <DateUtils>
 * @despriction 日期工具
 * @create 2018/01/08 14:47
 **/
@Component
public class DateUtils {
    @Autowired
    private CmsService cmsService;
    private interface DateConf {
        Long DAY = 24L * 3600L * 1000L; //天
        Long HOUR = 3600L * 1000L; //小时
        Long MINUTE = 60L * 1000L; //分
        Long SECOND = 1000L; //秒
    }

    public static final String yyyy_MM_dd ="yyyy-MM-dd";
    public static final String yyyy_MM_dd_HH_mm_ss ="yyyy-MM-dd HH:mm:ss";
    /**
     * 转换时间戳的差值 为 x天X时x分x秒
     *
     * @param time
     * @return
     */
    public static String transTime(Long time) {
        if (time == null) {
            return null;
        }
        Long d = time / DateConf.DAY,
                h = (time % DateConf.DAY) / DateConf.HOUR,
                m = (time % DateConf.HOUR) / DateConf.MINUTE,
                s = (time % DateConf.MINUTE) / DateConf.SECOND;
        return (d > 0 ? String.valueOf(d).concat("天") : "")
                .concat(h > 0 ? String.valueOf(h).concat("小时") : "")
                .concat(m > 0 ? String.valueOf(m).concat("分") : "")
                .concat(s >= 0 ? String.valueOf(s).concat("秒") : "");
    }

    /**
     * 转换时间戳的差值 为 x天
     *
     * @param time
     * @return
     */
    public static String transDate(Long time) {
        if (time == null) {
            return null;
        }
        Long d = time / DateConf.DAY;
        return (d > 0 ? String.valueOf(d).concat("天") : "");
    }


    /**
     * 转换时间戳的差值 为 x天X时x分x秒
     *
     * @param date1
     * @param date2
     * @return
     */
    public static String transTime(Date date1, Date date2) {
        if (date1 == null || date2 == null) {
            return null;
        }
        return transTime(Math.abs(date1.getTime() - date2.getTime()));
    }

    /**
     * 转换时间戳的差值 为 x天
     *
     * @param date1
     * @param date2
     * @return
     */
    public static String transDate(Date date1, Date date2) {
        if (date1 == null || date2 == null) {
            return null;
        }
        return transDate(Math.abs(date1.getTime() - date2.getTime()));
    }


    /**
     * 获取 某日 00:00:00  和 23:59:59
     *
     * @param date
     * @return
     */
    public static String[] getDayBetween(Date date) {
        String[] dateStrArr = new String[2];
        Calendar calendar = Calendar.getInstance();
        if (date != null) {
            calendar.setTime(date);
        }
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        dateStrArr[0] = DateUtil.dateToString(calendar.getTime());
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND, 0);
        dateStrArr[1] = DateUtil.dateToString(calendar.getTime());
        return dateStrArr;
    }
    
    /**
     * 时间戳转换为时间字符串
     * @param s
     * @return
     */
    public static String stampToDate(Long s){
        String res;
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date = new Date(s);
        res = simpleDateFormat.format(date);
        return res;
    }

    /*
     * @Author zsx
     * @Date 2018-08-17 04:08:54
     * @Description 将date转string
     * @param date
     * @return String
     */
    public static String dateString(Date date, String pattern){
        SimpleDateFormat f = new SimpleDateFormat(pattern);
        return date == null ? "" : f.format(date);
    }

    /*
     * @Author zsx
     * @Date 2018-08-22 08:08:16
     * @Description 将String类型的时间格式格式化成Date
     */
    public static Date getDate(String date, String pattern) {
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        try {
            return sdf.parse(date);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }


    /*
     * @Author zsx
     * @Date 2018-08-23 03:08:09
     * @Description 获取几天前后的时间
     * @param minute
     * @return Date
     */
    public static Date getFewDaysAgo(Integer minute){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.add(Calendar.DATE, minute);
        return calendar.getTime();
    }

    /**
     * 计算传入参数时间加上N个月之后的日期
     *@author liulei
     * @param date 当前时间
     * @param moth 月数
     * @return 结果
     * @throws ParseException 
     */
    public static Date dataAddMoth(Date date, int moth) throws ParseException {
        SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, moth);
        String T = fmt.format(calendar.getTime());
        return fmt.parse(T);
    }
    /**
     * 计算当期时间加上N天之后的日期
     *@author liuelei
     * @param date 当期日期
     * @param day  N天
     * @return N天后的日期
     * @throws ParseException 异常
     */
    public static Date dateAddDayJs(Date date, int day) throws ParseException {
    SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String dd = fmt.format(date);
        Date df = fmt.parse(dd);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(df);
        calendar.add(Calendar.DAY_OF_MONTH, day);
        String T = fmt.format(calendar.getTime());
        System.out.println(T);
        return fmt.parse(T);
    }

    /**
     * 两个日期比较大小
     *
     * @param DATE1
     * @param DATE2
     * @return
     */
    public static int compare_date(Date DATE1, Date DATE2) {


        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            Date dt1 = df.parse(df.format(DATE1));
            Date dt2 = df.parse(df.format(DATE2));
            if (dt1.getTime() > dt2.getTime()) {
                System.out.println("dt1 在dt2前");
                return 1;
            } else if (dt1.getTime() < dt2.getTime()) {
                System.out.println("dt1在dt2后");
                return -1;
            } else {
                return 0;
            }
        } catch (Exception exception) {
            exception.printStackTrace();
        }
        return 0;
    }

    /**
     * 获取下一个工作日的 23:59:59
     *
     * @param date
     * @return
     */
    public Date getNextWorkDateEnd(Date date) {
        SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd");
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        String dateStr = this.cmsService.findAfterDate(fmt.format(calendar.getTime()), 1);
        Assert.hasText(dateStr, "工作日获取失败！");
        try {
            Date nextWorkDate = fmt.parse(dateStr);
            Calendar overCalendar = Calendar.getInstance();
            overCalendar.setTime(nextWorkDate);
            overCalendar.set(Calendar.HOUR_OF_DAY, 23);
            overCalendar.set(Calendar.MINUTE, 59);
            overCalendar.set(Calendar.SECOND, 59);
            overCalendar.set(Calendar.MILLISECOND, 0);
            return overCalendar.getTime();
        } catch (ParseException e) {
            e.printStackTrace();
            throw new RuntimeException("工作日时间转换出现异常！");
        }
    }


    /**
     * 2018年6月14日 16:30:09
     * 修改  先计算预计完结时间 再按自然日 顺延 暂停总时长
     *
     * @param start
     * @param len
     * @param suspendMiniSec
     * @return
     */
    public Date getWorkDateFrom(Date start, Integer len, Long suspendMiniSec) {
        Date date = this.getWorkDateFrom(start, len);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MILLISECOND, suspendMiniSec.intValue());
        return calendar.getTime();
    }

    /**
     * 获取从某日开始x个工作日的日期
     *
     * @param start 开始日期
     * @param len   天数
     * @return
     */
    public Date getWorkDateFrom(Date start, Integer len) {
        SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd");
        Calendar calendarStart = Calendar.getInstance();
        calendarStart.setTime(start);
        Map map = new HashMap();
        map.put("date", fmt.format(start));
        map.put("days", len);
        String dateStr = this.cmsService.findAfterDate(fmt.format(start), len);
        Assert.hasText(dateStr, "获取工作日失败！");
        Date date = null;
        try {
            date = fmt.parse(dateStr);
            Calendar calendar1 = Calendar.getInstance();
            calendar1.setTime(date);
            calendar1.set(Calendar.HOUR_OF_DAY, calendarStart.get(Calendar.HOUR_OF_DAY));
            calendar1.set(Calendar.MINUTE, calendarStart.get(Calendar.MINUTE));
            calendar1.set(Calendar.SECOND, calendarStart.get(Calendar.SECOND));
            calendar1.set(Calendar.MILLISECOND, calendarStart.get(Calendar.MILLISECOND));
            return calendar1.getTime();
        } catch (ParseException e) {
            e.printStackTrace();
            Assert.isTrue(false, "工作日期转换出现异常！");
        }
        return date;
    }

    /**
     * 获取从某日开始x个自然日的日期
     *
     * @param start 开始日期
     * @param len   天数
     * @return
     */
    public Date getDateFrom(Date start, Integer len) {
        Calendar calendarStart = Calendar.getInstance();
        calendarStart.setTime(start);
        Calendar overCalendar = Calendar.getInstance();
        overCalendar.setTime(start);
        overCalendar.add(Calendar.DAY_OF_YEAR, len);
        overCalendar.set(Calendar.HOUR_OF_DAY, calendarStart.get(Calendar.HOUR_OF_DAY));
        overCalendar.set(Calendar.MINUTE, calendarStart.get(Calendar.MINUTE));
        overCalendar.set(Calendar.SECOND, calendarStart.get(Calendar.SECOND));
        overCalendar.set(Calendar.MILLISECOND, calendarStart.get(Calendar.MILLISECOND));
        return overCalendar.getTime();
    }


    /**
     * 获取代入暂停时间后的 从某日开始x个工作日的日期
     *
     * @param start          开始日期
     * @param len            天数
     * @param suspendMiniSec 暂停时长 单位: 毫秒
     * @return
     */
    private Date getDateFrom(Date start, Integer len, Long suspendMiniSec) {
        Calendar calendarStart = Calendar.getInstance();
        calendarStart.setTime(start);
        Calendar overCalendar = Calendar.getInstance();
        overCalendar.setTime(start);
        overCalendar.add(Calendar.DAY_OF_YEAR, len);
        overCalendar.add(Calendar.MILLISECOND, suspendMiniSec.intValue());
        return overCalendar.getTime();
    }

    /**
     * 计算日期 存在暂停时间时
     *
     * @param start          开始时间
     * @param len            天数
     * @param suspendMiniSec 暂停时长 ：毫秒
     * @param dateType       类型，常量定义于 WorkDayOrNaturalDayStatus
     * @return
     */
    public Date getDateFromStartByType(Date start, Integer len, Long suspendMiniSec, int dateType) {
        return ScProductConstant.WORKDAY_STATUS == dateType ?
                this.getWorkDateFrom(start, len, suspendMiniSec) : this.getDateFrom(start, len, suspendMiniSec);
    }

    /**
     * 计算日期
     *
     * @param start
     * @param len
     * @param dateType
     * @return
     */
    public Date getDateFromStartByType(Date start, Integer len, int dateType) {
        return ScProductConstant.WORKDAY_STATUS == dateType ?
                this.getWorkDateFrom(start, len) : this.getDateFrom(start, len);
    }
}
